Visualisation des données : Utilisation de Matplotlib, Seaborn, Plotly pour représenter des données avec Python¶

Resources¶

Packages official documentation

  • Matplotlib
  • Seaborn
  • Plotly
  • Dashboards

Cheatsheets

  • General
    • plots_theory
  • Matplotlib
    • Official matplotlib
      • matplotlib 1.1
      • matplotlib 2.1
      • matplotlib for beginners
    • By Datacamp
      • matplotlib
      • seaborn
  • Interactive graphs:
    • plotly

Démonstrations d'utilisation simple de Matplotlib, Seaborn et Plotly¶

In [ ]:
import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
In [ ]:
# Data
x = range(1000)
y = np.random.randn(1000)
z = np.random.randn(1000)
cat = np.random.randint(low=0, high=3, size=1000)
colors = np.random.randint(low=0, high=5, size=1000)

df = pd.DataFrame({'x': x, 'y': y, 'colors': colors, 'cat': cat})

Graphiques fondamentaux bruts¶

Line chart¶

Matplotlib

In [ ]:
# From matplotlib.pyplot directly
plt.plot(y)
Out[ ]:
[<matplotlib.lines.Line2D at 0x13b7c3130>]
In [ ]:
# From Pandas DataFrames
df.plot('x', 'y')
Out[ ]:
<AxesSubplot:xlabel='x'>

Seaborn

In [ ]:
# Activate Seaborn nice theme (will also be activated for standard matplotlib graphs)
sns.set_theme()
sns.lineplot(data=df, x='x', y='y')
Out[ ]:
<AxesSubplot:xlabel='x', ylabel='y'>

Plotly

In [ ]:
# You can zoom and hover with the mouse to see data values
px.line(df, 'x', 'y')

Scatter plot¶

Matplotlib

In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14a9006a0>
In [ ]:
# From Pandas DataFrames
df.plot.scatter('x', 'y')
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
Out[ ]:
<AxesSubplot:xlabel='x', ylabel='y'>

Seaborn

In [ ]:
sns.scatterplot(data=df, x='x', y='y')
Out[ ]:
<AxesSubplot:xlabel='x', ylabel='y'>

Plotly

In [ ]:
px.scatter(df, x='x', y='y')

Histogram¶

Matplotlib

In [ ]:
# From matplotlib.pyplot directly
plt.hist(y)
Out[ ]:
(array([  4.,  16.,  60., 146., 243., 274., 164.,  71.,  16.,   6.]),
 array([-3.38910972, -2.72965353, -2.07019735, -1.41074116, -0.75128498,
        -0.09182879,  0.56762739,  1.22708358,  1.88653976,  2.54599595,
         3.20545213]),
 <BarContainer object of 10 artists>)
In [ ]:
# From Pandas DataFrames
df['y'].hist()
Out[ ]:
<AxesSubplot:>

Seaborn

In [ ]:
sns.histplot(df['y'])
Out[ ]:
<AxesSubplot:xlabel='y', ylabel='Count'>

Plotly

In [ ]:
px.histogram(df['y'])

Couleurs - Coloration des points de données¶

In [ ]:
# Data
import random

colors_1 = ['b'] * 500 + ['r'] * 500
colors_2 = random.choices(['b', 'r'], k=1000)
In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y, c=colors_1)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14aac1040>
In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y, c=colors_2)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14acad1c0>

Comment est-ce que cela fonctionne ?

  • La couleur est attribuée en fonction de sa position dans la liste
  • Si un point de données (ici le chiffre 4) est en 3e position [9, 3, 4, 5, 8], alors la couleur qui lui sera attribuée sera en 3e position de la list des couleurs
  • ex : ['b', 'b', 'r', 'b', 'b']
In [ ]:
# Example simple
x_small = [0, 1, 2, 3, 4]
y_small = [9, 3, 4, 5, 8]
colors = ['b', 'b', 'b', 'r', 'b']
plt.scatter(x_small, y_small, c=colors)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14ad3d730>

Taille des points de données¶

In [ ]:
# Data
sizes_1 = [10] * 500 + [40] * 500
sizes_2 = random.choices([10, 40], k=1000)
In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y, c=colors_1, s=sizes_1)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14ad99820>
In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y, c=colors_2, s=sizes_2)
Out[ ]:
<matplotlib.collections.PathCollection at 0x14adf9100>

Comment est-ce que cela fonctionne ?

  • De même que les couleurs, l'attribution dépend de la position relative dans la liste

Markers - Type / forme des points de données¶

Marker identique sur l'ensemble des points¶

In [ ]:
# From matplotlib.pyplot directly
plt.scatter(x, y, c=colors_1, marker='+')
Out[ ]:
<matplotlib.collections.PathCollection at 0x14ae6cf70>

Multiples markers¶

  • Solution 0 (ne fonctionne pas) : définir une liste de markers
  • Solution 1 (ne pas faire car inefficient) : plotter chaque point les uns après les autres
  • Solution 2 : plotter un nouveau graph (avec ses points correspondants) pour chaque marker
In [ ]:
# Solution 2
plt.scatter(x[500:], y[500:], c=colors_1[500:], marker='+')
plt.scatter(x[:500], y[:500], c=colors_1[:500], marker='o')
Out[ ]:
<matplotlib.collections.PathCollection at 0x14aed5b80>

Graphiques spécifiques à chaque package¶

Matplotlib¶

  • Matplotlib permet de faire n'importequel type de graph, puisqu'il s'agit de la boîte à outil sur laquelle repose Seaborn.
  • Il est donc possible de reproduire les graphs de Seaborn en utilisant Matplotlib uniquement, mais cela demande bien plus d'efforts.
  • Pour plotly c'est différent, puisque le package repose sur plotly.js, écrit en javascript.
  • Inutile de s'y attaquer avec matplotlib. Par contre, leur forme en version statique pourra toujours être reproduite en matplotlib pur, avec une bonne volonté.

Seaborn¶

In [ ]:
sns.pairplot(df, hue='cat', height=2.5)
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x14ad14460>
In [ ]:
g = sns.jointplot(x="x", y="y", data=df, kind="reg")
  • Equivalent pairplot avec matplotlib
  • Equivalent jointplot avec matplotlib

Plotly¶

In [ ]:
import plotly.graph_objs as go
In [ ]:
parent_data = df[['colors', 'cat']].groupby('cat').value_counts()
parent_data = parent_data.reset_index()
In [ ]:
color_map = {0:'red', 1:'white', 2:'blue', 3:'green', 4:'pink'}
cat_map = {0:'cat_0', 1:'cat_1', 2:'cat_2'}
parent_data['colors'] = parent_data['colors'].replace(color_map)
parent_data['cat'] = parent_data['cat'].replace(cat_map)
In [ ]:
fig = px.sunburst(parent_data, path=['cat', 'colors'], values=0)
fig.show()

Aller plus loin:

  • plotly gallery

Missingno¶

In [ ]:
import missingno as msno
In [ ]:
df_with_na = df.copy()

# Random
idx_to_add_na_x = np.random.randint(df.shape[0], size=100)

# Correlated
idx_to_add_na_colors = np.random.randint(df.shape[0], size=60)
idx_to_add_na_cat = np.random.choice(idx_to_add_na_colors, size=40)
# Negatively correlated
remaining_idx_choices = df_with_na.index.drop(idx_to_add_na_x)
idx_to_add_na_y = np.random.choice(remaining_idx_choices, size=100)

# Add nans
df_with_na.loc[idx_to_add_na_y, 'y'] = np.nan
df_with_na.loc[idx_to_add_na_x, 'x'] = np.nan
df_with_na.loc[idx_to_add_na_colors, 'colors'] = np.nan
df_with_na.loc[idx_to_add_na_cat, 'cat'] = np.nan
In [ ]:
df_with_na
Out[ ]:
x y colors cat
0 0.0 0.191557 1.0 0.0
1 NaN 2.708459 3.0 2.0
2 2.0 NaN 0.0 2.0
3 3.0 1.798122 3.0 1.0
4 NaN -1.898219 3.0 2.0
... ... ... ... ...
995 995.0 -1.886973 1.0 2.0
996 996.0 -0.281315 4.0 0.0
997 997.0 0.764996 2.0 2.0
998 998.0 NaN 0.0 2.0
999 999.0 0.436428 1.0 0.0

1000 rows × 4 columns

In [ ]:
msno.matrix(df_with_na)
Out[ ]:
<AxesSubplot:>
In [ ]:
msno.bar(df_with_na)
Out[ ]:
<AxesSubplot:>
In [ ]:
msno.heatmap(df_with_na)
Out[ ]:
<AxesSubplot:>
In [ ]:
msno.dendrogram(df_with_na)
Out[ ]:
<AxesSubplot:>

Construction méthode manuelle¶

Permet davantage de flexibilité bien que moins facile à mettre en place

Matplotlib¶

Création de la figure, puis des axes

In [ ]:
fig = plt.figure(figsize=(8, 3))
ax = fig.add_subplot(1, 1, 1)
ax.scatter(df['x'], df['y']);

Création de la figure et des axes en une commande

In [ ]:
fig, axes = plt.subplots(1, 1, figsize=(8, 3))
axes.scatter(df['x'], df['y']);

Plotly¶

Création de la figure, puis des axes

In [ ]:
import plotly.graph_objects as go
fig = go.Figure()

fig.add_trace(go.Scatter(
    x=df['x'],
    y=df['y'],
    mode="markers+text",
    name="Markers and Text",
))

Construction d'une grille de graphs¶

Attaquons nous directement aux grilles de graphs, cela permet également de comprendre comment se crée un graph plus simple en détail :

  • Création d'une figure
  • Création d'axes
  • Génération d'un graph sur chaque axe

Matplotlib¶

Création basique d'une figure avec plusieurs graphs "subplots"

In [ ]:
fig, axes = plt.subplots(2, 3)

Création basique d'une figure avec plusieurs graphs et une taille spécifique "figsize"

In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7))

Ajout d'un premier graph (en haut à gauche)

In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7))
axes[0, 0].scatter(x, y)
Out[ ]:
<matplotlib.collections.PathCollection at 0x164b5a4f0>

Ajout de plusieurs graphs

In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7))
# Plots on first row
axes[0, 0].scatter(x, y)
axes[0, 1].scatter(x, y, c='red')
axes[0, 2].scatter(x, y, c='green')
# Plots on second row
axes[1, 0].scatter(x, y, marker='+')
axes[1, 1].scatter(x, y, marker='+', c='red')
axes[1, 2].scatter(x, y, marker='+', c='green')
Out[ ]:
<matplotlib.collections.PathCollection at 0x164a94610>

Ajout d'un titre, et de labels

In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7))
# Plots on first row
axes[0, 0].scatter(x, y)
axes[0, 1].scatter(x, y, c='red')
axes[0, 2].scatter(x, y, c='green')
# Plots on second row
axes[1, 0].scatter(x, y, marker='+')
axes[1, 1].scatter(x, y, marker='+', c='red')
axes[1, 2].scatter(x, y, marker='+', c='green')

# Title 
fig.suptitle('Multiple graphs')

# Label 1 (for top left plot)
axes[0, 0].set_xlabel('occurences')
axes[0, 0].set_ylabel('location')
# Label 2
axes[0, 1].set_xlabel('occurences')
axes[0, 1].set_ylabel('location')
# Label 3
axes[0, 2].set_xlabel('occurences')
axes[0, 2].set_ylabel('location')
# Label 4
axes[1, 0].set_xlabel('occurences')
axes[1, 0].set_ylabel('location')
# Label 5
axes[1, 1].set_xlabel('occurences')
axes[1, 1].set_ylabel('location')
# Label 6
axes[1, 2].set_xlabel('occurences')
axes[1, 2].set_ylabel('location')
Out[ ]:
Text(0, 0.5, 'location')
In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7))
# Plots on first row
axes[0, 0].scatter(x, y)
axes[0, 1].scatter(x, y, c='red')
axes[0, 2].scatter(x, y, c='green')
# Plots on second row
axes[1, 0].scatter(x, y, marker='+')
axes[1, 1].scatter(x, y, marker='+', c='red')
axes[1, 2].scatter(x, y, marker='+', c='green')

# Title 
fig.suptitle('Multiple graphs')

# Label 1 (for top left plot)
axes[0, 0].set_xlabel('occurences')
axes[0, 0].set_ylabel('location')
# Label 2
axes[0, 1].set_xlabel('occurences')
axes[0, 1].set_ylabel('location')
# Label 3
axes[0, 2].set_xlabel('occurences')
axes[0, 2].set_ylabel('location')
# Label 4
axes[1, 0].set_xlabel('occurences')
axes[1, 0].set_ylabel('location')
# Label 5
axes[1, 1].set_xlabel('occurences')
axes[1, 1].set_ylabel('location')
# Label 6
axes[1, 2].set_xlabel('occurences')
axes[1, 2].set_ylabel('location')

fig.tight_layout()

Partage d'axe entre les graphs: "sharex", "sharey"

In [ ]:
fig, axes = plt.subplots(2, 3, figsize=(10, 7), sharey='row')
# Plots on first row
axes[0, 0].scatter(x, y)
axes[0, 1].scatter(x, y, c='red')
axes[0, 2].scatter(x, y, c='green')
# Plots on second row
axes[1, 0].scatter(x, y, marker='+')
axes[1, 1].scatter(x, y, marker='+', c='red')
axes[1, 2].scatter(x, y, marker='+', c='green')

# Title 
fig.suptitle('Multiple graphs')

# Label 1 (for top left plot)
axes[0, 0].set_xlabel('occurences')
axes[0, 0].set_ylabel('location')
# croping the axis will benefit to other graphs in same row
axes[0, 0].set_ylim(0, 3)

# Label 2
axes[0, 1].set_xlabel('occurences')
# Label 3
axes[0, 2].set_xlabel('occurences')
# Label 4
axes[1, 0].set_xlabel('occurences')
axes[1, 0].set_ylabel('location')
# Label 5
axes[1, 1].set_xlabel('occurences')
axes[1, 1].set_ylabel('location')
# Label 6
axes[1, 2].set_xlabel('occurences')
axes[1, 2].set_ylabel('location')

fig.tight_layout()

Seaborn¶

Approche manuelle¶

Une approche consiste à utiliser les subplots de Matplotlib, et d'y insérer des graphs constitués avec Seaborn

In [ ]:
fig, axes = plt.subplots(2, 3)
sns.scatterplot(ax=axes[0, 0], x=x, y=y)
Out[ ]:
<AxesSubplot:>

Avec l'utilisation d'une DataFrame plutôt que des Numpy arrays :

  • x et y attendent les noms des colonnes de la DataFrame
  • et non plus les séries de données comme dans l'exemple précédent
In [ ]:
fig, axes = plt.subplots(2, 3)
sns.scatterplot(ax=axes[0, 0], data=df, x='x', y='y')
Out[ ]:
<AxesSubplot:xlabel='x', ylabel='y'>

Approche automatique¶

Une approche plus directe cependant repose sur l'utilisation des grilles Faceted de Seaborn

  • Il s'agit d'un objet qui repose sur les subplots
  • mais apporte des fonctionnalités pré-configurées

Il est possible d'utiliser ces grilles Faceted sans même les nommer

  • en passant plus simplement par la fonction relplot
  • elle se charge de créer la figure avec multiples cellules
  • et d'y insérer les graphs correspondants
In [ ]:
# Rappelez-vous des colonnes de notre DataFrame
df.head(3)
Out[ ]:
x y colors cat
0 0 0.191557 1 0
1 1 2.708459 3 2
2 2 0.353364 0 2
In [ ]:
sns.relplot(data=df, x='x', y='y', hue='colors', col='cat')
Out[ ]:
<seaborn.axisgrid.FacetGrid at 0x1654dba60>

Il est aussi possible d'obtenir un graph pour chaque paire de variables avec pairplot

In [ ]:
sns.pairplot(df, hue='cat', height=2.5)
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x1669a7d60>

Approche semi-automatique¶

Pour davantage de contrôle, il est possible d'utiliser :

  • "PairGrid" pour présenter les relations de paires de variables
  • "FacetGrid" pour présenter une même variables conditionnée par d'autres variables (groupby)

Il s'agit alors de décomposer en plusieurs étapes comme avec matplotlib:

  • une première création de la grille
  • l'attribution de graphs aux différentes parties de la grille
In [ ]:
# Pour les paires de variables
g = sns.PairGrid(df, hue="colors")
g.map_diag(sns.histplot)
g.map_offdiag(sns.scatterplot)
g.add_legend()
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x16523d5b0>
In [ ]:
# Contrôle diagonale, partie haute, partie basse
g = sns.PairGrid(df, hue='cat')
g.map_upper(sns.scatterplot)
g.map_lower(sns.kdeplot)
g.map_diag(sns.kdeplot, lw=3, legend=False)
Out[ ]:
<seaborn.axisgrid.PairGrid at 0x166dc1b80>
In [ ]:
# Pour l'affichage conditionnel d'une même variable
g = sns.FacetGrid(df, col="colors")
g.map(sns.histplot, "cat")
Out[ ]:
<seaborn.axisgrid.FacetGrid at 0x166d789a0>

Pour davantage d'exemples et d'explications: https://seaborn.pydata.org/tutorial/axis_grids.html

Autres types de données: audio, image (2D, 3D)¶

Audio¶

In [ ]:
# Download wav file
!wget -q "https://bigsoundbank.com/UPLOAD/wav/0003.wav" -O "data/audio.wav"

ref: https://dev.to/puritye/how-to-plot-an-audio-file-using-matplotlib-pbb

In [ ]:
# Load audio file
import wave
obj = wave.open('data/audio.wav', 'rb')
signal_wave = obj.readframes(-1)
signal_array = np.frombuffer(signal_wave, dtype=np.int16)
In [ ]:
# Compute duration and time ticks
print('Parameters:', obj.getparams())
sample_freq = obj.getframerate()
n_samples = obj.getnframes()
duration = n_samples/sample_freq
time = np.linspace(0, duration, num=n_samples)
Parameters: _wave_params(nchannels=1, sampwidth=2, framerate=44100, nframes=559930, comptype='NONE', compname='not compressed')

Plot signal wave¶

Matplotlib

In [ ]:
plt.figure(figsize=(15, 5))
plt.plot(time, signal_array)
plt.title('Audio Plot')
plt.ylabel('Signal wave')
plt.xlabel('Time (s)')
plt.xlim(0, max(time))
plt.show()

Seaborn

  • N'apporte rien par rapport à matplotlib sur ce type de graph (étant donné que le thème de seaborn est déjà activté pour matplotlib ci-dessus)

Plotly

In [ ]:
fig = go.Figure([go.Scatter(x=time, y=signal_array)])
fig.show()

Plot spectrum¶

In [ ]:
plt.figure(figsize=(15, 5))
plt.specgram(signal_array, Fs=sample_freq, vmin=-30, vmax=50)
plt.title('Left Channel')
plt.ylabel('Frequency (Hz)')
plt.xlabel('Time (s)')
plt.colorbar()
plt.show()

Image¶

2D¶

In [ ]:
# Download mri image
!wget -q "https://physionet.org/files/images/1.0.0/E1154S7I000.png?download" -O "data/img.png"
In [ ]:
# Load image
import matplotlib.image as mpimg
img = mpimg.imread('data/img.png')

Matplotlib

In [ ]:
# Plot image
plt.figure(figsize=(6,6))
plt.grid(visible=None)
plt.imshow(img)
Out[ ]:
<matplotlib.image.AxesImage at 0x16c189190>

Seaborn

In [ ]:
import seaborn_image as isns
fig, ax = plt.subplots(figsize=(6,6))
isns.imgplot(img, ax=ax)
Out[ ]:
<AxesSubplot:>

Plotly

In [ ]:
import plotly.express as px
fig = px.imshow(img)
fig.show()

3D¶

Matplotlib

  • https://jakevdp.github.io/PythonDataScienceHandbook/04.12-three-dimensional-plotting.html
In [ ]:
fig = plt.figure(figsize=(6,6))
ax = plt.axes(projection='3d')
In [ ]:
def f(x, y):
    return np.sin(np.sqrt(x ** 2 + y ** 2))

x = np.linspace(-6, 6, 30)
y = np.linspace(-6, 6, 30)

X, Y = np.meshgrid(x, y)
Z = f(X, Y)
In [ ]:
fig = plt.figure(figsize=(6, 6))
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 50, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
Out[ ]:
Text(0.5, 0, 'z')
In [ ]:
ax.view_init(60, 35)
fig
Out[ ]:

Plotly

  • https://plotly.com/python/3d-scatter-plots/
In [ ]:
import plotly.express as px
df_iris = px.data.iris()
fig = px.scatter_3d(df_iris, x='sepal_length', y='sepal_width', z='petal_width',
              color='species')
fig.show()

Pour davantage de possibilités

  • https://plotly.com/python/visualizing-mri-volume-slices/
  • https://dash.gallery/dash-brain-viewer/
  • https://dash.gallery/Portal/

Dessins, annotations¶

Lines verticles, horizontales¶

In [ ]:
df['y'].hist(bins=30)
plt.vlines([-2, 2], ymin=0, ymax=80, colors='r')
Out[ ]:
<matplotlib.collections.LineCollection at 0x16c5bce80>
In [ ]:
df.plot.scatter('x', 'y')
plt.hlines([-2, 2], xmin=0, xmax=1000, colors='r')
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
Out[ ]:
<matplotlib.collections.LineCollection at 0x16c5b9e20>

Formes¶

In [ ]:
df.plot.scatter('x', 'y')

bbox_props = {
    'boxstyle': 'circle',
    'pad': 2,
    'facecolor': 'none',
    'edgecolor': 'r',
}
plt.annotate("anomaly", (0, 3), bbox = bbox_props, clip_on=True)
plt.show()
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.

Annotations¶

Fleche manuelle¶

In [ ]:
df.plot.scatter('x', 'y')

# Position départ de la flêche (x, y), décalage par rapport au point de départ (x, y)
plt.arrow(600, 5, -280, -2.25, head_width=.3, head_length=25, linewidth=.5, color='r')
plt.text(610, 4.9, "anomaly", color='r', fontsize=15)
plt.show()
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
In [ ]:
df.plot.scatter('x', 'y')

plt.annotate(text='', xy=(133,-2.83), xytext=(410,-2.83), arrowprops=dict(arrowstyle='<->', color='r'))
plt.text(170, -3.3, "||AB||=277", color='r', fontsize=13)
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
Out[ ]:
Text(170, -3.3, '||AB||=277')

Fleche automatique¶

In [ ]:
df.plot.scatter('x', 'y')

# Position point fleche (xy), décalage (x, y%)
plt.annotate(
    r'$>1.96\sigma$', xy=(100, 2.7), xytext=(100,40), 
    textcoords='offset points', ha='center', va='bottom',color='k',
    bbox=dict(boxstyle='round,pad=0.2', fc='grey', alpha=0.35),
    arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0.2', 
    color='r'))
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
Out[ ]:
Text(100, 40, '$>1.96\\sigma$')
In [ ]:
 
In [ ]:
import plotly.graph_objects as go
fig = go.Figure()

fig.add_trace(go.Scatter(
    x=df['x'],
    y=df['y'],
    mode="markers+text",
    name="Markers and Text",
))

fig.add_trace(go.Scatter(
    x=[0, 400],
    y=[3, 3],
    mode="lines+text",
    name="Lines and Text",
    text=["Text G", "Text H", "Text I"],
    textposition="bottom center"
))

Export d'un graphique¶

In [ ]:
df['y'].hist()
plt.savefig('hist_y.pdf')
plt.savefig('hist_y.png')
In [ ]:
from matplotlib.backends.backend_pdf import PdfPages
with PdfPages('graph_list.pdf') as pdf:
    fig = plt.scatter(df['x'], df['y']).get_figure()
    pdf.savefig(fig)
    fig = df['y'].hist().get_figure()
    pdf.savefig(fig)

Generation de rapport automatique¶

In [ ]:
from pandas_profiling import ProfileReport
In [ ]:
profile = ProfileReport(df_with_na, title="Random data")
In [ ]:
profile.to_notebook_iframe()
Summarize dataset:   0%|          | 0/5 [00:00<?, ?it/s]
Generate report structure:   0%|          | 0/1 [00:00<?, ?it/s]
Render HTML:   0%|          | 0/1 [00:00<?, ?it/s]
In [ ]:
profile.to_file("random_data.html")
Export report to file:   0%|          | 0/1 [00:00<?, ?it/s]